//
//  MTNot.swift
//  onemeetingmac
//
//  Created by 张衡 on 2020/6/11.
//  Copyright © 2020 onemeeting. All rights reserved.
//

import Foundation

final class MTNot: NSObject {
    
    //单利
    static let shared = MTNot()
    
    //离开会议
    class func onExitRoom(isLeave:Bool=false) {
        Td.sh().cloud.isLeave = isLeave
        TXLiteManager.shared().exitRoom()
    }
    
    //视频开启关闭
    class func postNotVdOpen(isok:Bool,userid:String?=nil) {
        let info = UserMode()
        info.isVdOpen = isok
        info.userId = userid
        self.saveGlobalData(info:info)
        NotificationCenter.default.post(name: MTUserStateNotification, object: info)
    }

    //上麦
    class func postNotUpMicSwitch(isok:Bool,isConfirm:Bool,userid:String?=nil) {
        let info = AdcMode()
        info.userId = userid
        info.isUp = isok
        info.status = isConfirm ? .invite:.switch
        NotificationCenter.default.post(name: MTUpMicNotification, object: info)
    }
    
    class func postNotMessage(formId:String?,text:String?) {
        let mode = MessageMode()
        mode.fromUid = formId
        mode.text = text
        NotificationCenter.default.post(name: MTMessageNotification, object: mode)
    }
    
    //主持人收到上麦请求
    class func postNotUpMicRequest(isok:Bool,userid:String) {
        let info = AdcMode()
        info.userId = userid
        info.isUp = isok
        info.status = .request
        NotificationCenter.default.post(name: MTUpMicNotification, object: info)
    }
    
    class func postNotAllHandUp(userid:String?=nil) {
        MTNot.postNotHandUp(isok: false)
        
        for (inx,_) in Td.sh().usr.remote.enumerated() {
            Td.sh().usr.remote[inx].isHandUp = false
        }
        
        for (inx,_) in Td.sh().usr.adcs.enumerated() {
            Td.sh().usr.adcs[inx].isHandUp = false
        }
        NotificationCenter.default.post(name: MTADownHandUpNotification, object: ReloadNotification)
        MTNot.readHasHands()
        
    }
    class func postNotHandUp(isok:Bool,userid:String?=nil) {
        let info = UserMode()
        info.userId = userid
        info.isHandUp = isok
        self.saveGlobalData(info:info)
        NotificationCenter.default.post(name: MTUserStateNotification, object: info)
        
    }
    
    class func postNotMute(userid:String?=nil,isok:Bool?=nil) {
        let info = UserMode()
        if userid == nil {
            let localIsok = self.getLocalMute()
            info.isMute = localIsok
            info.userId = userid
        }else {
            info.isMute = isok
            info.userId = userid
        }
        self.saveGlobalData(info:info)
        NotificationCenter.default.post(name: MTUserStateNotification, object: info)
    }
    
    class func postHasUser(isok:Bool) {
        Td.sh().hasUser = isok
        NotificationCenter.default.post(name: MTHasUserVcNotification, object: isok)
    }
    
    class func postNotBarrge(text:String,userid:String?=nil,userName:String?=nil) {
        let nickName = self.getNickName(userid: userid) ?? userName
        let newData = ChatData.init(name: nickName ?? "...", text: text)
        Td.sh().chats.append(newData)
        let descriptor = self.walkTextSpriteDescriptorWithDirection(text: text,name:nickName)
        NotificationCenter.default.post(name: MTReviBarrgeNotification, object: descriptor)
    }
    
    /*
    依赖参数以下
    TXLiteManager.shared().isLiving
    TXLiteManager.shared().pushType
    //true 表示已经发生变化
    */
    class func postRTMPLive() {
        NotificationCenter.default.post(name: MTLIVENotification, object: ReloadNotification)
    }
    
    class func getNickName(userid:String?) -> String? {
        var nickName:String?
        if userid != nil {
            let uInfo = Td.sh().usr.remote.first { (info) -> Bool in
                return info.userId==userid
            }
            if let name = uInfo?.nickName {
                nickName = name
            }
        }else {
            nickName = Td.sh().lc.nickName
        }
        return nickName
    }
    
    class func postModyName(name:String,userid:String?=nil) {
        let info = UserMode()
        info.nickName = name
        info.userId = userid
        self.saveGlobalData(info: info) {
            NotificationCenter.default.post(name: MTUserStateNotification, object: info)
        }
    }
    
    
    class func saveGlobalData(info:UserMode,success:ResultNo?=nil) {
        
        if Td.isEnterRoom() == false {
            /*
            let queue = DispatchQueue.init(label: "asyncAfter")
            queue.suspend()
            queue.async {
                self.queueData(info: info,success: success)
            }
            */
            DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + DispatchTimeInterval.seconds(6)) {
                 self.queueData(info: info,success: success)
                //queue.resume()
                //print("info=\(info.nickName)")
            }
        }else {
            self.queueData(info: info,success: success)
        }
        
    }
    
    class func queueData(info:UserMode,success:ResultNo?=nil)  {
        let indx = Td.sh().usr.remote.firstIndex { (kInfo) -> Bool in
            return info.userId == kInfo.userId
        }
        if info.userId == nil {
            if let name = info.nickName {
                Td.sh().lc.nickName = name
            }
            if let isHandUp = info.isHandUp {
                Td.sh().lc.isHandUp = isHandUp
            }
            if let isVdOpen = info.isVdOpen {
                Td.sh().lc.isVdOpen = isVdOpen
            }
            if let isMute = info.isMute {
                print("isMute=\(isMute)")
                //Td.sh().lc.isMute = isMute
            }
        }else {
            if let index = indx {
                if let name = info.nickName {
                    Td.sh().usr.remote[index].nickName = name
                }
                if let isHandUp = info.isHandUp {
                    Td.sh().usr.remote[index].isHandUp = isHandUp
                }
                if let isVdOpen = info.isVdOpen {
                    Td.sh().usr.remote[index].isVdOpen = isVdOpen
                }
                if let isMute = info.isMute {
                    Td.sh().usr.remote[index].isMute = isMute
                }
            }
        }
        
        let adcInx = Td.sh().usr.adcs.firstIndex { (kInfo) -> Bool in
            return info.userId == kInfo.userId
        }
        if let index = adcInx {
            if let isHandUp = info.isHandUp {
                Td.sh().usr.adcs[index].isHandUp = isHandUp
            }
        }
        
        if info.isHandUp != nil {
            MTNot.readHasHands()
        }
        
        if success != nil {
            success!()
        }
    }
    
    
    class func readHasHands() {
        if let controller = TCGirdRender.shared().renderer.jk_viewcontroller() as? TCMeetViewController {
            controller.readHasHands()
            controller.tabarView.readHands()
        }else if let controller = TCGirdRender.shared().renderer.jk_viewcontroller() as? TCLiveViewController {
            controller.readHasHands()
            controller.tabarView.readHands()
        }
    }
    
    class func postFocusID(userID:String) {
        Td.sh().cloud.focusId = userID
        NotificationCenter.default.post(name: MTFocusChangeNotification, object: userID)
    }
    
    class func postLookID(userID:String) {
        Td.sh().cloud.lookId = userID
        NotificationCenter.default.post(name: MTLookChangeNotification, object: userID)
    }
    
    
    class func postHasSlipe(isok:Bool) {
        NotificationCenter.default.post(name: MTHasSplitNotification, object: isok)
    }
    
    class func postIsLoadingADc(userId:String,up:Bool) {
        let adcfirst = Td.sh().usr.adcs.firstIndex { (info) -> Bool in
            return userId == info.userId
        }
        if let index = adcfirst {
            Td.sh().usr.adcs[index].isLoading = up
        }
    }
    
    class func postAddAdc(userId:String?,name:String?) {
        var usr = AdcInfo()
        usr.userId = userId
        usr.nickName = name ?? "..."
        let remotefirst = Td.sh().usr.remote.firstIndex { (info) -> Bool in
            return userId == info.userId
        }
        let adcfirst = Td.sh().usr.adcs.firstIndex { (info) -> Bool in
            return userId == info.userId
        }
        if remotefirst != nil,name != nil {
            MTNot.postModyName(name: name!,userid: userId)
        }else if remotefirst == nil,adcfirst == nil{
            Td.sh().usr.adcs.append(usr)
            NotificationCenter.default.post(name: MTAddAdcNotification, object: usr)
        }
    }
    
    class func postDeleteAdc(userId:String?) {
        let index = Td.sh().usr.adcs.firstIndex { (info) -> Bool in
            return info.userId == userId
        }
        if let inx = index {
            Td.sh().usr.adcs.remove(at: inx)
            Td.sh().member = Td.sh().usr.adcs.count
            NotificationCenter.default.post(name: MTUserMemberNotification, object: Td.sh().member)
        }
        NotificationCenter.default.post(name: MTDeleteAdcNotification, object: userId)
        MTNot.readHasHands()
    }
    
    class func getNewUserMute() -> Bool {
        var isMute:Bool = false
        let scene = Td.sh().scene
        let isALLMute = Td.sh().cloud.isALLMute
        if scene == .meeting {
            isMute = true
        }else {
            if isALLMute {
                isMute = true
            }else {
                isMute = false
            }
        }
        return isMute
    }
    
    class func postAddUser(userId:String,name:String?) {
        IMEngine.shared.getUsersInfo(groupIDs: [userId], succ: { (result) in
            let memInfo =  result.filter { (info) -> Bool in
                return info.userID==userId
            }
            var userInfo = UserInfo()
            userInfo.userId = userId
            userInfo.nickName = memInfo[0].nickName ?? (name ?? "...")
            userInfo.isMute = self.getNewUserMute()
            
            let isok = Td.sh().usr.remote.contains { (info) -> Bool in
                return (info.userId==userId)
            }
            if isok == false {
                Td.sh().usr.remote.append(userInfo)
                NotificationCenter.default.post(name: MTAddUsersNotification, object: userInfo)
            }
        }) { (code, msg) in
            
        }
    }
    
    class func postDeleteUser(userId:String) {
        var userInfo = UserInfo()
        userInfo.userId = userId
        let isok = Td.sh().usr.remote.contains { (info) -> Bool in
            return (info.userId==userId)
        }
        
        if isok == true {
            Td.sh().usr.remote.lremove(userid: userId)
            NotificationCenter.default.post(name: MTDeleteUsersNotification, object: userInfo)
            MTNot.readHasHands()
        }
    }
    
    class func walkTextSpriteDescriptorWithDirection(direction:Int=Int(BarrageWalkDirection.R2L.rawValue),text:String,name:String?) -> BarrageDescriptor{
        let descriptor = BarrageDescriptor.init()
        descriptor.spriteName = BarrageWalkTextSprite.className()
        descriptor.params["text"] = text
        descriptor.params["textColor"] = color_random_rgba()
        descriptor.params["speed"] = (100*Double(arc4random())/Double(RAND_MAX)+30)
        descriptor.params["direction"] = Int(direction)
        descriptor.params["attributedText"] = NSAttributedString.stringBybarrage(text: text, name: name)
        return descriptor
    }
    
    class func getLocalMute(local:Bool=Td.sh().lc.isMute,all:Bool=Td.sh().cloud.isALLMute) -> Bool {
        var isok:Bool = false
        if String.isHostId() {
            isok = local
        }else {
            if all == true {
                isok = true
            }else {
                isok = local
            }
        }
        return isok
    }
}

extension NSAttributedString  {
    class func stringBybarrage(text:String,name:String?) -> NSAttributedString? {
        var params:[String:Any] = [:]
        params["text"] = text
        params["textColor"] = color_gray(220)
        if let userName = name {
            params["name"] = userName
            params["nameColor"] = color_random_rgba()
        }
        return NSAttributedString.initDescriptor(params: params)
    }
    
    class func initDescriptor(params:[String:Any]) -> NSAttributedString?{
        let textColor = (params["textColor"] as? NSColor) ?? NSColor.white
        if let text =  params["text"] as? String {
            let attribText = NSMutableAttributedString.init(string: text)
            attribText.addAttributes([NSAttributedString.Key.foregroundColor:textColor], range: NSRange.init(location: 0, length: text.count))
            if let name =  params["name"] as? String {
                let kName = name+": "
                let nameColor =  params["nameColor"] as? NSColor ?? color_gray(200)
                let attribName = NSMutableAttributedString.init(string: kName)
                attribName.addAttributes([NSAttributedString.Key.foregroundColor:nameColor], range: NSRange.init(location: 0, length: kName.count))
                attribText.insert(attribName, at: 0)
            }
            return attribText
        }
        return nil
    }
}
